package com.tom.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.RabbitListenerContainerFactory;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

//RabbitMQ配置类
@Configuration
public class RabbitMQConfig {

    //交换机
    public static final String EXCHANGE_TOPIC_KILL = "EXCHANGE_TOPIC_KILL";
    //延迟队列
    public static final String QUEUE_DELAY_KILL = "QUEUE_DELAY_KILL";
    //死信队列
    public static final String QUEUE_DEAD_KILL = "QUEUE_DEAD_KILL";

    //定义交换机
    @Bean
    public Exchange exchange(){
        return ExchangeBuilder.topicExchange(EXCHANGE_TOPIC_KILL).durable(true).build();
    }
    //定义延迟队列
    @Bean
    public Queue delayQueue(){
        Map<String,Object> map = new HashMap<>();
        map.put("x-dead-letter-exchange", EXCHANGE_TOPIC_KILL);    //过期的消息给哪个交换机的名字
        map.put("x-dead-letter-routing-key", "order.dead");   //死信交换机把消息个哪个个routingkey
        map.put("x-message-ttl", 20000);    //队列过期时间20s
        return new Queue(QUEUE_DELAY_KILL,true,false,false,map);
    }
    //定义死信队列
    @Bean
    public Queue deadQueue(){
        return new Queue(QUEUE_DEAD_KILL);
    }
    //绑定队列到交换机
    @Bean
    public Binding delayQueueBind(){
        return BindingBuilder.bind(delayQueue()).to(exchange()).with("order.delay").noargs();
    }
    @Bean
    public Binding deadQueueBind(){
        return BindingBuilder.bind(deadQueue()).to(exchange()).with("order.dead").noargs();
    }


    //定义RabbitTemplate 指定 JSON转换器
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(new Jackson2JsonMessageConverter());
        //1.把要发送的消息内容 ，交换机，rontkey等都保存下来到Mysql
        //2.后续可以用来重写发送消息，甚至可以使用一个定时任务不停的重试，可以甚至一个最大重试次数
        //设置消息回调
        rabbitTemplate.setMandatory(true);
        return rabbitTemplate;
    }

    //定义 监听器的工厂 ，定义JSON的转换器
    @Bean("rabbitListenerContainerFactory")
    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        //消息转换器;JSON
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        factory.setConcurrentConsumers(3);
        factory.setMaxConcurrentConsumers(10);
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        factory.setPrefetchCount(1);
        return factory;
    }
}